package br.com.iswe.gerador.velocity.gerador;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import br.com.iswe.gerador.velocity.info.InfoEntidadeImpl;
import br.com.iswe.gerador.velocity.info.InfoGerador;

public class GeradorJSP extends GeradorBase {

	private static final String TRUE = "true";
	public static final String GERADOR_JSP_PACKAGE_FROM = "gerador.jsp.package.from";
	public static final String GERADOR_JSP_PACKAGE_TO = "gerador.jsp.package.to";
	
	private static final String GERADOR_JSP_PASTA_SAIDA = "gerador.jsp.pasta.saida";
	
    private static final String JSP_CONSULTA_VM = "JSP-CONSULTA.vm";
    private static final String CSS_VM = "CSS.vm";
	private static final String JSP_POP_UP_CONSULTA_VM = "JSP-POPU-UP-CONSULTA.vm";
	private static final String JSP_POP_UP_DETAIL_VM = "JSP-POPU-UP-DETAIL.vm";
	private static final String JSP_POP_UP_LOOKUP_VM = "JSP-POPU-UP-LOOKUP.vm";
	private static final String JSP_DETALHE_VM = "JSP-DETALHE.vm";
	
    private static final String CONSULTA_JSP = "Consulta.jsp";
    private static final String LAYOUT_CSS = "layout.css";
	private static final String POP_UP_CONSULTA_JSP = "PopUpConsulta.jsp";
	private static final String POP_UP_DETAIL_JSP = "PopUpDetalhe.jsp";
	private static final String POP_UP_LOOKUP_JSP = "PopUpLookUp.jsp";
	private static final String DETALHE_JSP = "Detalhe.jsp";
	
	public static final String NOME_GERADOR = "geradorJSP";

	private InfoGerador infoGerador;
	
	public void gerarCodigo(InfoEntidadeImpl info) throws Exception  {
		String arquivoSaida = null;
        //Primeiro Passo : Cria o contexto com as informa��es necess�rias para criar a classe de BO.
		VelocityContext ctx = buildContext(this.infoGerador);
		//Adiciona a info da entidade
		ctx.put(InfoEntidadeImpl.NOME_INFO, info);
		//Obt�m o package do BO que � necess�rio na classe WBean
		String packageJSP = info.getReplacePackage(GeradorJSP.GERADOR_JSP_PACKAGE_FROM, GeradorJSP.GERADOR_JSP_PACKAGE_TO);
		
		//Segundo Passo : Obt�m o diret�rio onde ser� gerado o fonte de sa�da.
		String basePath = infoGerador.getPastaBaseSaida() + SEPARADOR + infoGerador.getPropriedade(GERADOR_JSP_PASTA_SAIDA);
		File pathSaida = new File(basePath + SEPARADOR + infoGerador.getPathFromPackage(packageJSP) + SEPARADOR + info.getNomeEntidade2());
		//Verifica se o path ja existe
		if(!pathSaida.exists()){
			pathSaida.mkdirs();
		}

		//Quarto Passo : 
		//Gerando a pagina de consulta
		Template template = null;
		Writer wrt = null;
		arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + CONSULTA_JSP;
		if( infoGerador.shouldGenerateFile(arquivoSaida) ){
			template = Velocity.getTemplate(JSP_CONSULTA_VM);
			//Escreve o arquivo de sa�da
			wrt = new OutputStreamWriter(new FileOutputStream(arquivoSaida), CHARSET_UTF);
			//Gera o documento.
			template.merge(ctx, wrt);
			//Descarrega para o disco.
			wrt.flush();
			wrt.close();
		}
        
        //Quinto Passo : 
        //Gerando o css da pagina de consulta
        //verifica se deve gerar o arquivo.
        arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + LAYOUT_CSS;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
            template = Velocity.getTemplate(CSS_VM);
            //Escreve o arquivo de sa�da
            wrt = new OutputStreamWriter(new FileOutputStream(arquivoSaida), CHARSET_UTF);
            //Gera o documento.
            template.merge(ctx, wrt);
            //Descarrega para o disco.
            wrt.flush();
            wrt.close();
        }

        arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + POP_UP_DETAIL_JSP;
		//Verifica se a entidade � um detalhe de um mestre.
		if(TRUE.equals(info.getPropriedade(InfoEntidadeImpl.IS_COLL_REF_DETAIL)) && infoGerador.shouldGenerateFile(arquivoSaida)){
			//Gerando o JSP de pop-up
			template = Velocity.getTemplate(JSP_POP_UP_DETAIL_VM);
			//Escreve o arquivo de sa�da
			wrt = new OutputStreamWriter(new FileOutputStream(arquivoSaida), CHARSET_UTF);
			//Gera o documento.
			template.merge(ctx, wrt);
			//Descarrega para o disco.
			wrt.flush();
			wrt.close();
		}
		
		arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + DETALHE_JSP;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
			//Gerando a pagina de detalhe
			template = Velocity.getTemplate(JSP_DETALHE_VM);
			//Escreve o arquivo de sa�da
			wrt = new OutputStreamWriter(new FileOutputStream(arquivoSaida), CHARSET_UTF);
			//Gera o documento.
			template.merge(ctx, wrt);
			//Descarrega para o disco.
			wrt.flush();
			wrt.close();
        }
		
        arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + POP_UP_CONSULTA_JSP;
		//Verifica se a entidade � referencia em forma de colecao em otra entidade
		if(TRUE.equals(info.getPropriedade(InfoEntidadeImpl.IS_COLL_REF)) && infoGerador.shouldGenerateFile(arquivoSaida)){
			//Gerando o JSP de pop-up
			template = Velocity.getTemplate(JSP_POP_UP_CONSULTA_VM);
			//Escreve o arquivo de sa�da
			wrt = new OutputStreamWriter(new FileOutputStream(arquivoSaida), CHARSET_UTF);
			//Gera o documento.
			template.merge(ctx, wrt);
			//Descarrega para o disco.
			wrt.flush();
			wrt.close();
		}
		
		arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + POP_UP_LOOKUP_JSP; 
		//Verifica se a entidade � referencia em otra entidade
		if(TRUE.equals(info.getPropriedade(InfoEntidadeImpl.IS_OBJ_REF)) && infoGerador.shouldGenerateFile(arquivoSaida)){
			//Gerando o JSP de pop-up
			template = Velocity.getTemplate(JSP_POP_UP_LOOKUP_VM);
			//Escreve o arquivo de sa�da
			wrt = new OutputStreamWriter(new FileOutputStream(arquivoSaida), CHARSET_UTF);
			//Gera o documento.
			template.merge(ctx, wrt);
			//Descarrega para o disco.
			wrt.flush();
			wrt.close();
		}
	}

	public void inicio(InfoGerador infoGerador) {
		this.infoGerador = infoGerador;
	}

	public void fim() {
		this.infoGerador = null;
	}
}
